package com.jonluo.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jonluo.common.exception.RReturnException;
import com.jonluo.common.utils.EnvVariable;
import com.jonluo.common.utils.MenuType;
import com.jonluo.common.utils.R;
import com.jonluo.common.utils.UuidUtils;
import com.jonluo.entity.MenuEntity;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.*;

/**
 * 系统菜单
 * @author com.jonluo
 * Date 2017/9/15
 */
@RestController
@RequestMapping("/sys/menu")
public class MenuController extends AbstractController {

    @Autowired
    RestTemplate restTemplate;
    @Autowired
    EnvVariable envVariable;

    /**
     * 导航菜单
     */
    @RequestMapping("/nav")
    public R nav() {
        JSONObject json = new JSONObject();
        json.put("menuIdList", "");
        String resultJson = null;
        JSONObject resultMap = null;

        if (envVariable.getSuperAdminId().equals(getCurrentUserId())) {
            //系统管理员，拥有最高权限
            json.put("menuIdList", "-1");
        }else {
            //获取用户菜单ids
            resultJson =  restTemplate.getForEntity(envVariable.getBaseUrl()+"/user/getAllMenuIdById/"+getCurrentUserId(), String.class).getBody();
            resultMap = JSONObject.parseObject(resultJson);
            if (0 == resultMap.getInteger("code")){
            List<String> list = (List) resultMap.get("data");
            json.put("menuIdList", StringUtils.join(list.toArray(),","));
            }
        }
        List<MenuEntity> menuList = getUserMenuListOrSubMenu("0",json.getString("menuIdList"),true);

        //获取权限
        Set<String> permissions = getUserPermissions(getCurrentUserId());


        return R.ok().put("menuList", menuList).put("permissions", permissions);
    }

    /**
     * 所有菜单列表
     */
    @RequestMapping("/list")
    @RequiresPermissions("sys:menu:list")
    public List<MenuEntity> list() {
        return  getAllMenu(null);
    }

    /**
     * 选择菜单(添加、修改菜单)
     */
    @RequestMapping("/select")
    @RequiresPermissions("sys:menu:select")
    public R select() {
        //查询非按钮列表数据
        JSONObject para = new JSONObject();
        para.put("type","0,1");
        List<MenuEntity> menuList = getAllMenu(para);
        //添加顶级菜单
        MenuEntity root = new MenuEntity();
        root.setMenuId("0");
        root.setName("一级菜单");
        root.setParentId("-1");
        root.setOpen(true);
        menuList.add(root);
        return R.ok().put("menuList", menuList);
    }


    /**
     * 菜单信息
     */
    @RequestMapping("/info/{menuId}")
    @RequiresPermissions("sys:menu:info")
    public R info(@PathVariable("menuId") String menuId) {
        MenuEntity menu = getById(menuId);
        return R.ok().put("menu", menu);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    @RequiresPermissions("sys:menu:save")
    public R save(@RequestBody MenuEntity menu) {
        menu.setMenuId(UuidUtils.getUUID("menu"));
        //数据校验
        verifyForm(menu);

        String resultJson = restTemplate.postForEntity(envVariable.getBaseUrl()+"/menu/add",menu, String.class).getBody();
        JSONObject resultMap = JSONObject.parseObject(resultJson);
        if(0 == resultMap.getInteger("code")){
            return R.ok("success");
        }else {
            return R.error("fail");
        }
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    @RequiresPermissions("sys:menu:update")
    public R update(@RequestBody MenuEntity menu) {
        //数据校验
        verifyForm(menu);

        String resultJson = restTemplate.postForEntity(envVariable.getBaseUrl()+"/menu/update",menu, String.class).getBody();
        JSONObject resultMap = JSONObject.parseObject(resultJson);
        if(0 == resultMap.getInteger("code")){
            return R.ok("success");
        }else {
            return R.error("fail");
        }
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    @RequiresPermissions("sys:menu:delete")
    public R delete(String menuId) {
        /*if (Integer.parseInt() <= 31) {
            return R.error("系统菜单，不能删除");
        }*/
        //判断是否有子菜单或按钮
        List<MenuEntity> menuList = getUserMenuListOrSubMenu(menuId,"-1",false);
        if (menuList.size() > 0) {
            return R.error("请先删除子菜单或按钮");
        }
        JSONObject json = new JSONObject();
        json.put("menuIds", menuId);
        String resultJson = restTemplate.postForEntity(envVariable.getBaseUrl()+"/menu/deleteByIds",json, String.class).getBody();
        //删除角色与菜单关系
        resultJson = restTemplate.postForEntity(envVariable.getBaseUrl()+"/roleMenu/deleteByRoleIdsOrMenuIds",json, String.class).getBody();
        JSONObject resultMap = JSONObject.parseObject(resultJson);
        if(0 == resultMap.getInteger("code")){
            return R.ok("success");
        }else {
            return R.error("fail");
        }
    }

    /**
     * 获取用户菜单或子菜单
     * @param isAll 对应 true 或false
     * @return
     */
    public List<MenuEntity> getUserMenuListOrSubMenu(String parentId, String menuIdList , boolean isAll){
        JSONObject json = new JSONObject();
        json.put("isAll",isAll);
        json.put("parentId", parentId);
        json.put("menuIdList",menuIdList );
        String resultJson = restTemplate.postForEntity(envVariable.getBaseUrl() + "/menu/getUserMenuList", json, String.class).getBody();
        JSONObject resultMap = JSONObject.parseObject(resultJson);
        List<MenuEntity> menuList = null;
        if (0 == resultMap.getInteger("code")){
            menuList =  (List<MenuEntity>) resultMap.get("data");
        }
        return menuList;
    }

    /**
     * 获取菜单
     * @param paraJson
     * @return
     */
    public List<MenuEntity> getAllMenu(JSONObject paraJson){
        JSONObject json = new JSONObject();
        if (paraJson != null){
            json.put("params",paraJson);
        }
        String resultJson = restTemplate.postForEntity(envVariable.getBaseUrl()+"/menu/getAll",json, String.class).getBody();
        JSONObject resultMap = JSONObject.parseObject(resultJson);
        List<MenuEntity> menuList = null;
        if ( 0 == resultMap.getInteger("code")){
            menuList  = JSONArray.parseArray(resultMap.getJSONArray("data").toJSONString(),MenuEntity.class);
        }
        return menuList;
    }

    /**
     * 通过id获取菜单
     * @param menuId
     * @return
     */
    public MenuEntity getById(String menuId){
        MenuEntity menu = null ;
        String resultJson = restTemplate.getForEntity(envVariable.getBaseUrl()+"/menu/getById/"+menuId, String.class).getBody();
        JSONObject resultMap = JSONObject.parseObject(resultJson);
        if ( 0 == resultMap.getInteger("code")){
            menu = resultMap.getObject("data",MenuEntity.class);
        }else {
            menu = new MenuEntity();
        }
        return  menu;
    }


    public Set<String> getUserPermissions(String userId) {
        List<String> permsList = null;
        //系统管理员，拥有最高权限
        if(envVariable.getSuperAdminId().equals(userId)){
            List<MenuEntity> menuList = getAllMenu(null);
            permsList = new ArrayList<>(menuList.size());
            for(MenuEntity menu : menuList){
                permsList.add(menu.getPerms());
            }
        }else{
            String resultJson = restTemplate.getForEntity(envVariable.getBaseUrl()+"/user/getAllPermsById/"+userId, String.class).getBody();
            JSONObject resultMap = JSONObject.parseObject(resultJson);
            if ( 0 == resultMap.getInteger("code")){
                permsList = (List<String>) resultMap.get("data");
            }
        }
        //用户权限列表
        Set<String> permsSet = new HashSet<>();
        for(String perms : permsList){
            if(StringUtils.isBlank(perms)){
                continue;
            }
            permsSet.addAll(Arrays.asList(perms.trim().split(",")));
        }
        return permsSet;
    }


    /**
     * 验证参数是否正确
     */
    private void verifyForm(MenuEntity menu) {
        switch (menu.getType()){
            //目录
            case 0:
                menu.setUrl("");
                menu.setPerms("");
                break;
            //按钮
            case 2:
                menu.setUrl("");
                menu.setIcon("");
                break;
            default :break;
        }

        if (StringUtils.isBlank(menu.getName())) {
            throw new RReturnException("菜单名称不能为空");
        }

        if (menu.getParentId() == null) {
            throw new RReturnException("上级菜单不能为空");
        }

        //菜单
        if (menu.getType() == MenuType.MENU.getValue()) {
            if (StringUtils.isBlank(menu.getUrl())) {
                throw new RReturnException("菜单URL不能为空");
            }
        }

        //菜单
        if (menu.getMenuId().equals( menu.getParentId())) {
                throw new RReturnException("上级菜单不能为本身");
        }


        //上级菜单类型
        int parentType = MenuType.CATALOG.getValue();
        if (!"0".equals(menu.getParentId())) {
            MenuEntity parentMenu = getById(menu.getParentId());
            parentType = parentMenu.getType();
        }

        //目录、菜单
        if (menu.getType() == MenuType.CATALOG.getValue() ||
                menu.getType() == MenuType.MENU.getValue()) {
            if (parentType != MenuType.CATALOG.getValue()) {
                throw new RReturnException("上级菜单只能为目录类型");
            }
            return;
        }

        //按钮
        if (menu.getType() == MenuType.BUTTON.getValue()) {
            if (parentType != MenuType.MENU.getValue()) {
                throw new RReturnException("上级菜单只能为菜单类型");
            }
            return;
        }
    }
}
